/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * TestFrame.java
 *
 * Created on 13-Jul-2010, 21:03:54
 */
package astroim;

import astroim.samp.LocalConnector;
import astroim.samp.ProxyClient;
import astroim.smack.Connection;
import astroim.smack.CustomChatListener;
import java.awt.Toolkit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;
import org.astrogrid.samp.Client;
import org.astrogrid.samp.Response;
import org.astrogrid.samp.client.ResultHandler;
import org.astrogrid.samp.client.SampException;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smackx.ServiceDiscoveryManager;
import org.jivesoftware.smackx.packet.DiscoverItems;

/**
 *
 * @author alykhalid
 */
public class AstroIMMessaging extends javax.swing.JFrame implements MessageListener {
    private boolean discoCalled = false;
    /** Creates new form TestFrame */
    public AstroIMMessaging() {
        initComponents();

       
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane3 = new javax.swing.JScrollPane();
        jTextArea2 = new javax.swing.JTextArea();
        jLabel1 = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();

        setName("Form"); // NOI18N

        jScrollPane3.setName("jScrollPane3"); // NOI18N

        jTextArea2.setColumns(20);
        jTextArea2.setLineWrap(true);
        jTextArea2.setRows(5);
        jTextArea2.setWrapStyleWord(true);
        jTextArea2.setName("jTextArea2"); // NOI18N
        jTextArea2.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jTextArea2KeyPressed(evt);
            }
            public void keyReleased(java.awt.event.KeyEvent evt) {
                jTextArea2KeyReleased(evt);
            }
        });
        jScrollPane3.setViewportView(jTextArea2);

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(astroim.AstroIMApp.class).getContext().getResourceMap(AstroIMMessaging.class);
        jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N
        jLabel1.setName("jLabel1"); // NOI18N

        jScrollPane2.setName("jScrollPane2"); // NOI18N

        jTextArea1.setColumns(20);
        jTextArea1.setEditable(false);
        jTextArea1.setLineWrap(true);
        jTextArea1.setRows(5);
        jTextArea1.setName("jTextArea1"); // NOI18N
        jScrollPane2.setViewportView(jTextArea1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 285, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 285, Short.MAX_VALUE)
                    .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 285, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 90, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jTextArea2KeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextArea2KeyPressed
        int key = evt.getKeyCode();
        if (key == java.awt.event.KeyEvent.VK_ENTER) {
            if(!"".equalsIgnoreCase(jTextArea2.getText())){
                sendMessage(jTextArea2.getText());
                jTextArea1.append("Me: " + jTextArea2.getText() + newline);
            }
        }
    }//GEN-LAST:event_jTextArea2KeyPressed

    private void jTextArea2KeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextArea2KeyReleased
        int key = evt.getKeyCode();
        if (key == java.awt.event.KeyEvent.VK_ENTER) {
            jTextArea2.setText("");
            
        }
    }//GEN-LAST:event_jTextArea2KeyReleased

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new AstroIMMessaging().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel jLabel1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JTextArea jTextArea2;
    // End of variables declaration//GEN-END:variables

    private final static String newline = "\n";

    public void processMessage(Chat chat, Message msg) {
        this.JID = chat.getParticipant();
        if (!discoCalled) {
            Disco();
            discoCalled = true;
        }
        if (!msg.getBody().isEmpty()) {
            if(msg.getBody().compareTo("@SampHub")==0){
                //System.out.println("Message Received by @SampHub");
                String RecipientID = (String) msg.getProperty("RecipientID");
                System.out.println("RecipientID: " + RecipientID);
                LocalConnector lc = LocalConnector.getInstance();
                org.astrogrid.samp.Message newMsg = MakeNewMsg(msg);
                newMsg.check();
                try {
                    lc.connection.call(RecipientID, newMsg, new ResultHandler() {

                        public void result(Client responder, Response response) {
                            System.out.println("Response Received");
                        }

                        public void done() {
                            System.out.println("Done");
                        }
                    }, 3);
                } catch (SampException ex) {
                    System.out.println(ex.getMessage());
                    Logger.getLogger(AstroIMMessaging.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            if (!this.isVisible()) {
                System.out.println("Calling Set Visible");
                this.setVisible(true);
            }
            System.out.println("Message Received by Not Empty");
            jLabel1.setText(JID);
            jTextArea1.append(JID + ": " + msg.getBody() + newline);
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    jTextArea1.setCaretPosition(jTextArea1.getText().length());
                }
            });

            
        }
    }
    private ChatManager chatmanager = Connection.getInstance().getConnection().getChatManager();
    private Chat newChat;
    private String JID = "";

    public AstroIMMessaging ProcessChat(String jid) {
        this.JID = jid;
        if (!CustomChatListener.getInstance().getChatters().containsKey(JID)) {
            CustomChatListener.getInstance().getChatters().put(jid, this);
            Disco();
        }
        jLabel1.setText(jid);
        if (!this.isVisible()) {
            this.setVisible(true);
        }
       
        return this;
    }

    public void sendMessage(String msg) {
        newChat = chatmanager.createChat(JID, CustomChatListener.getInstance().getChatters().get(JID));
        try {
            if (newChat != null) {
                if (!msg.isEmpty()) {
                    newChat.sendMessage(msg);
                }
            } else if (!msg.isEmpty()) {
                chatmanager.createChat(JID, this).sendMessage(msg);
            }
        } catch (XMPPException ex) {
            Logger.getLogger(AstroIMMessaging.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void sendMessage(org.jivesoftware.smack.packet.Message msg) {
        System.out.print("Sent Message Called");
        newChat = chatmanager.createChat(JID, CustomChatListener.getInstance().getChatters().get(JID));
        try {
            newChat.sendMessage(msg);
        } catch (XMPPException ex) {
            Logger.getLogger(AstroIMMessaging.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    //private ArrayList<ProxyClient> RegisteredProxyClients = new ArrayList<ProxyClient>();

    private void Disco() {
        HashMap<String, String> ClientProperties = new HashMap<String, String>();
        String ProxyName = "";
        String ProxyID = "";
        try {
            ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(Connection.getInstance().getConnection());
            //ServiceDiscoveryManager discoManager = new ServiceDiscoveryManager(Connection.getInstance().getConnection());
            //System.out.println("DiscoManager: " + discoManager.discoverItems(JID, "astronomy").toXML());
            Iterator<DiscoverItems.Item> it = discoManager.discoverItems(JID, "astronomy").getItems();
            while(it.hasNext()){
                DiscoverItems.Item individualItem = (DiscoverItems.Item)it.next();
                System.out.println(individualItem.toXML());
                System.out.println(individualItem.getName());
                if("".compareToIgnoreCase(ProxyName) == 0){
                    ProxyID = individualItem.getName().split("/")[0];
                    ProxyName = individualItem.getName().split("/")[1];
                    ClientProperties.put(individualItem.getName().split("/")[2], "");
                } else if(individualItem.getName().split("/")[1].compareToIgnoreCase(ProxyName) == 0){
                    ClientProperties.put(individualItem.getName().split("/")[2], "");
                } else if(individualItem.getName().split("/")[1].compareToIgnoreCase(ProxyName) != 0){
                    ProxyClient pc = new ProxyClient();
                    Connection.getInstance().RegisteredProxyClients.add(pc.setAimm(this)
                            .setClientName(JID)
                            .setProxyID(ProxyID)
                            .setName(ProxyName)
                            .setDescription("")
                            .setRegisteredSubscriptions(ClientProperties)
                            .registerWithHub());
                    ClientProperties.clear();

                    ProxyID = individualItem.getName().split("/")[0];
                    ProxyName = individualItem.getName().split("/")[1];
                    ClientProperties.put(individualItem.getName().split("/")[2], "");
                }
            }
            ProxyClient pc = new ProxyClient();
            Connection.getInstance().RegisteredProxyClients.add(pc.setAimm(this)
                    .setClientName(JID)
                    .setProxyID(ProxyID)
                    .setName(ProxyName).setDescription("")
                    .setRegisteredSubscriptions(ClientProperties)
                    .registerWithHub());
        } catch (SampException ex) {
            System.out.println("Smap Exception");
            Logger.getLogger(AstroIMMessaging.class.getName()).log(Level.SEVERE, null, ex);
        } catch (XMPPException ex) {
            System.out.println("XMPP Exception");
            Logger.getLogger(AstroIMMessaging.class.getName()).log(Level.SEVERE, null, ex);
        }


    }

    private org.astrogrid.samp.Message MakeNewMsg(org.jivesoftware.smack.packet.Message msg) {
        String MType = (String)msg.getProperty("MType");
        System.out.println("MType: " + MType);
        org.astrogrid.samp.Message newMsg = new org.astrogrid.samp.Message(MType);
        System.out.println("Msg Property Coll Size:" + msg.getPropertyNames().size());

        for(String s : msg.getPropertyNames()){
            System.out.println("Entering Loop");
            if(("MType".compareTo(s) != 0) && ("RecipientID".compareTo(s) != 0)){
                System.out.println("Params: " + s + " : " + msg.getProperty(s));
                newMsg.addParam(s, msg.getProperty(s));
            }
        }
        return newMsg;
    }
}
